#coding=utf8
import psutil
import json
import requests
import os
import logging  # 引入logging模块
import os.path
import time
import sched
from datetime import datetime



# 第一步，创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # Log等级总开关

def initLogger():
    # 第二步，创建一个handler，用于写入日志文件
    rq = time.strftime('%Y%m%d', time.localtime(time.time()))
    log_path = os.getcwd() + '/logs/'
    if not os.path.exists(log_path):
        os.mkdir(log_path)
    log_name = log_path + rq + '.log'
    logfile = log_name
    fh = logging.FileHandler(logfile, mode='a')
    fh.setLevel(logging.DEBUG)  # 输出到file的log等级的开关
    # 第三步，定义handler的输出格式
    formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
    fh.setFormatter(formatter)
    # 第四步，将logger添加到handler里面
    logger.addHandler(fh)


#获取CPU信息
def getCpuInfo():
    cpu_count = psutil.cpu_count(logical=False)  #1代表单核CPU，2代表双核CPU
    xc_count = psutil.cpu_count()                #线程数，如双核四线程
    cpu_slv = round((psutil.cpu_percent(1)), 2)  # cpu使用率
    list = [cpu_count,xc_count,cpu_slv]
    return list

#获取内存信息
def getMemoryInfo():
    memory = psutil.virtual_memory()
    total_nc = round(( float(memory.total) / 1024 / 1024 / 1024), 2)  # 总内存
    used_nc = round(( float(memory.used) / 1024 / 1024 / 1024), 2)  # 已用内存
    free_nc = round(( float(memory.free) / 1024 / 1024 / 1024), 2)  # 空闲内存
    syl_nc = round((float(memory.used) / float(memory.total) * 100), 2)  # 内存使用率

    ret_list = [total_nc,used_nc,free_nc,syl_nc]
    return ret_list


#获取硬盘信息
def getDiskInfo():
    list = psutil.disk_partitions() #磁盘列表
    ilen = len(list) #磁盘分区个数
    i=0
    retlist1=[]
    retlist2=[]
    while i< ilen:
        diskinfo = psutil.disk_usage(list[i].device)
        total_disk = round((float(diskinfo.total)/1024/1024/1024),2) #总大小
        used_disk = round((float(diskinfo.used) / 1024 / 1024 / 1024), 2) #已用大小
        free_disk = round((float(diskinfo.free) / 1024 / 1024 / 1024), 2) #剩余大小
        syl_disk = diskinfo.percent

        retlist1=[i,list[i].device,total_disk,used_disk,free_disk,syl_disk]  #序号，磁盘名称，
        retlist2.append(retlist1)
        i=i+1

    return retlist2

#获取网络信息
def getNetInfo():
    netcard_info = []
    info = psutil.net_if_addrs()
    for k,v in info.items():
        for item in v:
            if item[0] == 2 and not item[1]=='127.0.0.1':
                netcard_info.append((k,item[1]))
    return netcard_info



def getSysInfo():
    cpuInfo = getCpuInfo()
    memoryInfo = getMemoryInfo()
    diskInfo = getDiskInfo()
    netInfo = getNetInfo()

    osInfo = os.uname()

    sysInfo = {
        "os" : osInfo[0],
        "hostname": osInfo[1],
        "kernelVersion": osInfo[2],
        "hardArch": osInfo[4],
        "cpuInfo": {
            "cpuCount": cpuInfo[0],
            "threadCount": cpuInfo[1],
            "usedRate": cpuInfo[2]
        },
        # ret_list = [total_nc,used_nc,free_nc,syl_nc]
        "memInfo":{
            "total": memoryInfo[0],
            "used": memoryInfo[1],
            "free": memoryInfo[2],
            "usedRate": memoryInfo[3]
        },
        "diskInfo":[],
        "netInfo":[]
    }

    #retlist1=[i,list[i].device,total_disk,used_disk,free_disk,syl_disk]  #序号，磁盘名称，
    for disk in diskInfo:
        sysInfo["diskInfo"].append({"serial":disk[0],"label":disk[1],"size": disk[2],"used":disk[3],"free": disk[4],"usedRate": disk[5]})

    for net in netInfo:
        sysInfo["netInfo"].append({"name":net[0],"ip":net[1]})
    return sysInfo

def uploadInfo(inc):
    sysInfo = getSysInfo()
    sysInfoJson = json.dumps(sysInfo, sort_keys=True, indent=4, separators=(',', ': '))
    logger.info(sysInfoJson)
    headers = {'Content-Type': 'application/json'}
    uploadUrl = "http://127.0.0.1:8080/drux-monitor/api/monitor/uploadInfo"
    logger.info(u"发送监控信息到"+uploadUrl)
    r = requests.post(url=uploadUrl,headers=headers,data=sysInfoJson)
    if r.status_code == requests.codes.ok:
        jsonNode = json.loads(r.text)
        if jsonNode["success"]:
           logger.info(u"监控信息上传成功")
        else:
            logger.error(u"监控信息上传失败:"+jsonNode["errorMsg"])
    else:
        logger.error(u"http错误码:"+str(r.status_code)+u",错误信息:"+r.text)
        #r.raise_for_status()  # 抛出异常
    schedule.enter(inc, 0, uploadInfo, (inc,))
    
    
if __name__ == '__main__':
    initLogger()
    # 第一个参数是一个可以返回时间戳的函数，第二个参数可以在定时未到达之前阻塞。
    schedule = sched.scheduler(time.time, time.sleep)
    # 给该触发函数的参数（tuple形式）
    schedule.enter(0, 0, uploadInfo, (60,))
    schedule.run()
    

    
